package cn.chengpengper.im.platform.common.risk.window.impl;

import cn.chengpengper.im.platform.common.model.constants.ImPlatformContants;
import cn.chengpengper.im.platform.common.risk.window.SlidingWindowLimitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
@ConditionalOnProperty(name = "distributed.cache.type", havingValue = "redis")
public class RedisSlidingWindowLimitService implements SlidingWindowLimitService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean passThough(String key, long windowPeriod, int windowSize) {
        String redisKey = ImPlatformContants.getKey(ImPlatformContants.PLATFORM_REDIS_USER_KEY, key);
        long currentTimeMillis = System.currentTimeMillis();
        long length = windowPeriod * windowSize;
        long start = currentTimeMillis - length;
        // 计算过期时间
        long expireTime = length + windowPeriod;
        redisTemplate.opsForZSet().add(redisKey, String.valueOf(currentTimeMillis), currentTimeMillis);
        // 移除[0,start]区间的值
        redisTemplate.opsForZSet().removeRangeByScore(redisKey, 0, start);
        // 获取窗口内元素的个数
        Long count = redisTemplate.opsForZSet().zCard(redisKey);
        redisTemplate.expire(redisKey, expireTime, TimeUnit.MILLISECONDS);
        if (Objects.isNull(count)) {
            return false;
        }
        return count <= windowSize;
    }
}
